home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / assembler / progasm1.lha / LEZIONI / LEZIONE6.TXT < prev    next >
Text File  |  1994-11-27  |  24KB  |  604 lines

  1.  
  2.  CORSO DI ASSEMBLER - LEZIONE 6
  3.  
  4. In questa lezione vedremo come visualizzare dei testi sullo schermo, come
  5. far scorrere schermi piu' grandi della finestra video, e l'uso delle tabelle
  6. di valori predefiniti per simulare movimenti di rimbalzo e ondeggiamento.
  7.  
  8. Imparare a visualizzare delle scritte sullo schermo e' importantissimo, non
  9. si puo' fare a meno di una routine di stampa caratteri in un gioco o in una
  10. demo grafica: se vogliamo scrivere il punteggio e il numero delle vite, o un
  11. messaggio tra un livello e l'altro, oppure il dialogo tra i personaggi, una
  12. scritta con i saluti agli amici, eccetera.
  13. E' chiaro che non vengono visualizzate delle figure 320x256 con le scritte
  14. gia' fatte! Immaginatevi di voler visualizzare 5 pagine di testo per introdurre
  15. la storia del vostro gioco: "un cavaliere di un periodo storico imprecisato
  16. decise di andare alla ricerca del santo graal..." eccetera.
  17. Le soluzioni sono due: o vi disegnate col programma da disegno cinque figure
  18. col testo stampato, e in questo caso avremmo 5 figure da 40*256 = 51200 byte
  19. utilizzati, che vi rubano spazio su disco e memoria, oppure con 1k di FONT
  20. caratteri e pochi byte di routine che stampa quei caratteri fate lo stesso
  21. lavoro, risparmiando 50k.
  22. Avrete presenti i FONT di caratteri del sistema operativo: TOPAZ,DIAMOND
  23. eccetera, che potete scegliere?
  24. Ebbene a noi non interessano i FONT di sistema, perche' ne usiamo di nostri.
  25. Si possono usare anche i font di sistema, ma sono limitati, mentre
  26. facendosi i font e la routine che stampa i caratteri di quel font si possono
  27. visualizzare scritte di qualsiasi dimensione, anche colorate, basta disegnare
  28. il font e farsi la routine giusta.
  29. Una volta capito il sistema di PRINT, ossia di STAMPA dei caratteri si possono
  30. fare variazioni senza difficolta'.
  31. Per cominciare vediamo come stampare un font piccolo, largo 8 pixel e alto 8,
  32. ad un solo colore.
  33. Come prima cosa bisogna disporre di un BITPLANE dove stampare il testo e di
  34. un FONT CARATTERI dove sono disegnati tutti i caratteri da copiare.
  35. Per il bitplane non ci sono problemi, infatti basta crearsi nel listato un
  36. pezzo di memoria azzerato della dimensione di un bitplane, e "puntarlo", ossia
  37. farlo visualizzare. Per fare uno spazio azzerato si puo' usare
  38. il comando DCB.B 40*256,0 che, appunto, crea uno spazio azzerato della
  39. dimensione giusta; ma esiste una SECTION specifica per i "BUFFER" azzerati:
  40. la section BSS, in cui si puo' usare la sola direttiva DS.B/DS.w/DS.l, che
  41. stabilisce quanti bytes/word/longword azzerati creare. Il vantaggio sta nella
  42. lunghezza finale del FILE ESEGUIBILE: mentre creando lo spazio azzerato
  43. con un: "BITPLANE: dcb.b  40*256,0" i 10240 bytes sono aggiunti alla lunghezza
  44. totale del file, definendo una Section BSS:
  45.  
  46.     SECTION    UnBitplaneQua,BSS_C    ; _C significa che deve essere caricata
  47.                     ; in CHIP RAM, senza il _C verrebbe
  48.                     ; caricata dove capita, anche in FAST!
  49.                     ; ma i bitplane devono essere in CHIP.
  50. BITPLANE:
  51.     ds.b    40*256        ; 10240 bytes a zero
  52.  
  53. Al file verra' aggiunto un HUNK di pochi bytes che "varra'" 40*256 bytes al
  54. momento del caricamento in memoria del file. Il "dcb.b 40*256,0" e' come
  55. avere un ingombrante sacchetto di monete da 100 lire, mentre il "ds.b 40*256"
  56. e' come un piccolo biglietto da 100.000 lire. Il risultato e' lo stesso, ma
  57. il file e' piu' snello.
  58.  
  59. Da notare che il "ds.b 40*256" non e' seguito dal ",0" come nel "DCB", infatti
  60. il "DS" indica sempre degli zeri, mentre il DCB puo' mettere in memoria un
  61. qualsiasi valore ripetuto X volte.
  62.  
  63. Ora abbiamo il "PEZZO DI CARTA" dove scrivere le nostre cose, ma non abbiamo
  64. ne' il font ne' la routine che stampa.
  65. Vediamo cosa e' un FONT e come e' fatto. Un font e' un file che contiene
  66. le parole e i numeri necessari per scrivere, e puo' essere di vari formati.
  67. Il font non e' altro che una fila di caratteri uno sotto l'altro, precisamente
  68. sono TUTTI i caratteri in fila: "ABCDEFGHI...".
  69. Certi font sono disegnati in .IFF, cioe' una schermata con i caratteri:
  70.  
  71.      ------------
  72.     |ABCDEFGHIJKL|
  73.     |MNOPQRSTUVWX|
  74.     |YZ1234567890|
  75.     |         |
  76.     |         |
  77.      ------------
  78.  
  79. Il disegno viene poi convertito in RAW, e i caratteri sono presi da quella
  80. figura e copiati nel bitplane: se va stampata una "A", viene copiata dal FONT
  81. in RAW al BITPLANE, con dei move, e la "A" appare sul bitplane. Cosi' ogni
  82. volta che serve una "A" sappiamo dove si trova e la copiamo dal FONT, cosi'
  83. per le altre lettere.
  84. Parliamo del sistema usato nei font 8x8 in questo corso: i caratteri occupano
  85. 8 pixel*8pixel, dunque sono grandi come il FONT del kickstart. In realta' sono
  86. piu' stretti in quanto devono contenere anche la "spaziatura" di un pixel tra
  87. una parola e l'altra, o la scrittura sembrerebbe in corsivo!!
  88. I caratteri poi sono messi nell'ordine "giusto", ossia che rispetta quello
  89. ASCII, che e' il seguente:
  90.  
  91.     dc.b    $1f,' !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO'
  92.     dc.b    'PQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~',$7F
  93.  
  94. Il $1f iniziale e il $7f finale indicano che il primo carattere, lo SPAZIO,
  95. e' quello dopo il $1f, ossia il $20, segue "!" che e' il $21 eccetera, mentre
  96. dopo gli ultimi caratteri si arriva al $7f. Questo e' per darvi un'idea della
  97. disposizione dei caratteri ASCII. Abbiamo gia' parlato del fatto che i numeri
  98. possono essere anche caratteri ASCII, basta provare con un "?$21", verificando
  99. che il risultato viene dato in esadecimale ($), decimale, ASCII "...!", e
  100. binario. Abbiamo anche visto che un:
  101.  
  102.     dc.b    "CANE"
  103.  
  104. E' equivalente ad un:
  105.  
  106.     dc.b    $63,$61,$6e,$65
  107.  
  108. Infatti "C" in memoria e' $63, "A" e' $61 eccetera.
  109. Ogni carattere infatti occupa un byte in memoria, e un testo lungo 5000 bytes
  110. contiene 5000 caratteri.
  111. Ritornando al nostro font, immaginatevi una figura larga solo 8 pixel, e alta
  112. abbastanza da contenere tutti i caratteri posti l'uno sotto l'altro:
  113.  
  114. !
  115. "
  116. #
  117. $
  118. %
  119. &
  120. '
  121. (
  122. )
  123. *
  124. +
  125. ,
  126. -
  127. .
  128. /
  129. 0
  130. 1
  131. 2
  132. 3
  133. 4
  134. 5
  135. 6
  136. 7
  137. 8
  138. 9
  139. :
  140. ;
  141. <
  142. =
  143. >
  144. ?
  145. @
  146. A
  147. B
  148. C
  149. D
  150. E
  151. F
  152. G
  153. H
  154. I
  155. J
  156. K
  157. L
  158. M
  159. N
  160. O
  161.  
  162. ECCETERA ECCETERA..... 
  163.  
  164. Il font 8x8 che usiamo nel corso non e' altro che una figura del genere in RAW.
  165. In realta' questo tipo di font viene fatto normalmente con un apposito EDITOR,
  166. un programma dedicato al disegno di questi font 8x8 ad un colore.
  167. Per i font piu' grandi e colorati pero' conviene disegnare le lettere in una
  168. figura, normalmente 320x256, e usare una routine propria per prelevare i
  169. caratteri da stampare. Per cominciare pero' vediamo il font piu' semplice come
  170. viene stampato a video: innanzitutto bisogna preparare una stringa di testo
  171. con le parole da stampare, ad esempio:
  172.  
  173.     dc.b    "Prima scritta!"    ; nota: si possono usare '' oppure ""
  174.  
  175.     EVEN                ; ossia allinea ad indirizzo PARI
  176.  
  177. La direttiva EVEN serve ad evitare gli indirizzi dispari per le istruzioni o
  178. i dati che si trovano sotto il dc.b. Le stringhe di testo sono composte
  179. di bytes e puo' succedere che siano un numero dispari, in tal caso la label
  180. sottostante sara' ad un indirizzo dispari, e questo puo' generare errori di
  181. assemblaggio: infatti, nel 68000, le istruzioni devono sempre essere ad
  182. indirizzi pari, e anche i dati dovrebbero essere ad indirizzi pari per evitare
  183. GURU MEDITATION in fase di esecuzione, infatti un MOVE.L o MOVE.W eseguito su
  184. un indirizzo dispari causa un bel Crash con GURU MEDITATION ed esplosioni.
  185. Ricordatevi dunque di mettere sempre un EVEN al termine di una stringa di
  186. testo, o di accertarvi che sia pari.
  187. Potete anche aggiungere uno zero in piu' al termine della stringa per
  188. pareggiare il conto, come ho fatto per GfxName:
  189.  
  190. GfxName:
  191.     dc.b    "graphics.library",0,0
  192.  
  193. Potete scrivere anche:
  194.  
  195. GfxName:
  196.     dc.b    "graphics.library",0
  197.     even
  198.  
  199. Infatti basta uno zero alla fine del testo, l'altro lo mettera' EVEN.
  200. Dunque, una volta stabilita la stringa di testo da visualizzare, basta vedere
  201. come copiare i caratteri giusti al posto giusto.
  202. Vi propongo gia' la routine che stampa un carattere:
  203.  
  204. PRINT:
  205.     LEA    TESTO(PC),A0    ; Indirizzo del testo da stampare in a0
  206.     LEA    BITPLANE,A3    ; Indirizzo del bitplane destinazione in a3
  207.     MOVEQ    #0,D2        ; Pulisci d2
  208.     MOVE.B    (A0),D2        ; Prossimo carattere in d2
  209.     SUB.B    #$20,D2        ; TOGLI 32 AL VALORE ASCII DEL CARATTERE, IN
  210.                 ; MODO DA TRASFORMARE, AD ESEMPIO, QUELLO
  211.                 ; DELLO SPAZIO (che e' $20), in $00, quello
  212.                 ; DELL'ASTERISCO ($21), in $01...
  213.     MULU.W    #8,D2        ; MOLTIPLICA PER 8 IL NUMERO PRECEDENTE,
  214.                 ; essendo i caratteri alti 8 pixel
  215.     MOVE.L    D2,A2
  216.     ADD.L    #FONT,A2    ; TROVA IL CARATTERE DESIDERATO NEL FONT...
  217.  
  218.                 ; STAMPIAMO IL CARATTERE LINEA PER LINEA
  219.     MOVE.B    (A2)+,(A3)    ; stampa LA LINEA 1 del carattere
  220.     MOVE.B    (A2)+,40(A3)    ; stampa LA LINEA 2  " "
  221.     MOVE.B    (A2)+,40*2(A3)    ; stampa LA LINEA 3  " "
  222.     MOVE.B    (A2)+,40*3(A3)    ; stampa LA LINEA 4  " "
  223.     MOVE.B    (A2)+,40*4(A3)    ; stampa LA LINEA 5  " "
  224.     MOVE.B    (A2)+,40*5(A3)    ; stampa LA LINEA 6  " "
  225.     MOVE.B    (A2)+,40*6(A3)    ; stampa LA LINEA 7  " "
  226.     MOVE.B    (A2)+,40*7(A3)    ; stampa LA LINEA 8  " "
  227.  
  228.     RTS
  229.  
  230. Avete gia' capito???
  231. Analizziamola punto per punto:
  232.  
  233.     LEA    TESTO(PC),A0    ; Indirizzo del testo da stampare in a0
  234.     LEA    BITPLANE,A3    ; Indirizzo del bitplane destinazione in a3
  235.     MOVEQ    #0,D2        ; Pulisci d2
  236.     MOVE.B    (A0),D2        ; Prossimo carattere in d2
  237.  
  238. Fino a qua non ci sono problemi, abbiamo in d2 il valore del carattere, se
  239. fosse una "A", allora abbiamo $41 in d2
  240.  
  241.     SUB.B    #$20,D2        ; TOGLI 32 AL VALORE ASCII DEL CARATTERE, IN
  242.                 ; MODO DA TRASFORMARE, AD ESEMPIO, QUELLO
  243.                 ; DELLO SPAZIO (che e' $20), in $00, quello
  244.                 ; DELL'ASTERISCO ($21), in $01...
  245.  
  246. Anche qua cosa succede e' chiaro, vediamo perche' sottraiamo 32 ($20):
  247.  
  248.     MULU.W    #8,D2        ; MOLTIPLICA PER 8 IL NUMERO PRECEDENTE,
  249.                 ; essendo i caratteri alti 8 pixel
  250.     MOVE.L    D2,A2
  251.     ADD.L    #FONT,A2    ; TROVA IL CARATTERE DESIDERATO NEL FONT...
  252.  
  253. Questa operazione porta ad avere in A2 l'indirizzo del carattere "A" presente
  254. nel font, ossia l'indirizzo da dove dobbiamo "prendere" il carattere per
  255. copiarlo nel bitplane che stiamo visualizzando.
  256. Vediamo cosa e' successo: ricordate che i caratteri sono stati messi nel font
  257. nello stesso ordine dello standard ASCII? Per cui, disponendo del valore
  258. ASCII del carattere, in questo caso $41 per la "A", possiamo individuare a che
  259. distanza dall'inizio del FONT si trova la "A" in RAW! Se ogni carattere e' di
  260. 8x8 pixel, significa che e' lungo 8 bit, ossia un byte a linea * 8 linee, in
  261. totale 8 bytes.
  262. Dunque lo spazio (il primo carattere nel FONT) si trova all'inizio del FONT
  263. stesso e finisce al byte 8, dove inizia "!" (il secondo) , e cosi' via.
  264. Avendo sottratto $20 al valore ASCII, il valore dello spazio diventera' $00, il
  265. carattere successivo "!" $01, eccetera (la "A" risultera' $21), dunque basta
  266. moltiplicare per 8 il numero ottenuto dopo la sottrazione per ricavare la
  267. distanza, dall'inizio del FONT, del carattere in questione!!! Rivediamo il
  268. passaggio:
  269.  
  270.     SUB.B    #$20,D2        ; TOGLI 32 AL VALORE ASCII DEL CARATTERE, IN
  271.                 ; MODO DA TRASFORMARE, AD ESEMPIO, QUELLO
  272.                 ; DELLO SPAZIO (che e' $20), in $00, quello
  273.                 ; DELL'ASTERISCO ($21), in $01...
  274.     MULU.W    #8,D2        ; MOLTIPLICA PER 8 IL NUMERO PRECEDENTE,
  275.                 ; essendo i caratteri alti 8 pixel
  276.  
  277. Ora in D2 abbiamo la distanza (l'offset) dell'inizio del carattere dall'inizio
  278. del FONT! Ora per trovare l'indirizzo effettivo del carattere, aggiungiamo
  279. la "distanza dall'inizio" che abbiamo in D2 all'indirizzo del FONT:
  280.  
  281.     MOVE.L    D2,A2
  282.     ADD.L    #FONT,A2    ; TROVA IL CARATTERE DESIDERATO NEL FONT...
  283.  
  284. Ora abbiamo in a2 l'indirizzo dove si trova il nostro carattere da copiare,
  285. ad esempio la "A". Bastera' ora copiarla da FONT allo schermo, cioe' al
  286. BITPLANE 320x256, in cui ogni linea e' lunga 40 bytes:
  287.  
  288.                 ; STAMPIAMO IL CARATTERE LINEA PER LINEA
  289.     MOVE.B    (A2)+,(A3)    ; stampa LA LINEA 1 del carattere
  290.     MOVE.B    (A2)+,40(A3)    ; stampa LA LINEA 2  " "
  291.     MOVE.B    (A2)+,40*2(A3)    ; stampa LA LINEA 3  " "
  292.     MOVE.B    (A2)+,40*3(A3)    ; stampa LA LINEA 4  " "
  293.     MOVE.B    (A2)+,40*4(A3)    ; stampa LA LINEA 5  " "
  294.     MOVE.B    (A2)+,40*5(A3)    ; stampa LA LINEA 6  " "
  295.     MOVE.B    (A2)+,40*6(A3)    ; stampa LA LINEA 7  " "
  296.     MOVE.B    (A2)+,40*7(A3)    ; stampa LA LINEA 8  " "
  297.  
  298. La copia avviene per "linee", infatti il carattere e' alto 8 linee, ognuna
  299. delle quali e' larga 8 bit (1 byte):
  300.  
  301.     12345678
  302.  
  303.     ...###.. linea    1 - 8 bit, 1 byte
  304.     ..#...#. 2
  305.     ..#...#. 3
  306.     ..#####. 4
  307.     ..#...#. 5
  308.     ..#...#. 6
  309.     ..#...#. 7
  310.     ........ 8
  311.  
  312. Dunque per copiarlo una linea alla volta occorre copiarne un byte alla volta.
  313. Ma lo schermo destinazione e' largo 40 bytes per linea, e dobbiamo considerare
  314. che ogni linea deve essere allineata l'una sotto l'altra, se non saltiamo 40
  315. bytes ogni volta copieremmo cosi' il carattere:
  316.  
  317.     ...###....#...#...#...#...#####...#...#...#...#...#...#.........
  318.  
  319. Invece dobbiamo copiare un byte, poi ANDARE A CAPO saltando 40 bytes, e
  320. copiare un'altro byte:
  321.  
  322.     MOVE.B    (A2)+,(A3)    ; stampa LA LINEA 1 del carattere
  323.  
  324. Sul monitor:
  325.  
  326.     ...###..
  327.  
  328.     MOVE.B    (A2)+,40(A3)    ; stampa LA LINEA 2 (40 bytes dopo)
  329.  
  330. Sul monitor:
  331.  
  332.     ...###..
  333.     ..#...#.
  334.  
  335.  
  336.     MOVE.B    (A2)+,40*2(A3)    ; stampa LA LINEA 3 (80 bytes dopo)
  337.  
  338. Sul monitor:
  339.  
  340.     ...###..
  341.     ..#...#.
  342.     ..#...#.
  343.  
  344. Eccetera. Per uno schermo largo 80 bytes (640x256 HIRES) basterebbe cambiare
  345. la routine cosi':
  346.  
  347.     MOVE.B    (A2)+,(A3)    ; stampa LA LINEA 1 del carattere
  348.     MOVE.B    (A2)+,80(A3)    ; stampa LA LINEA 2  " "
  349.     MOVE.B    (A2)+,80*2(A3)    ; stampa LA LINEA 3  " "
  350.     MOVE.B    (A2)+,80*3(A3)    ; stampa LA LINEA 4  " "
  351.     MOVE.B    (A2)+,80*4(A3)    ; stampa LA LINEA 5  " "
  352.     MOVE.B    (A2)+,80*5(A3)    ; stampa LA LINEA 6  " "
  353.     MOVE.B    (A2)+,80*6(A3)    ; stampa LA LINEA 7  " "
  354.     MOVE.B    (A2)+,80*7(A3)    ; stampa LA LINEA 8  " "
  355.  
  356. Vediamo in pratica la stampa di questa "A" su un bitplane in Lezione6a.s
  357.  
  358. Ora passeremo a stampare un'intera riga di testo con Lezione6b.s
  359.  
  360. E infine stampiamo quante righe vogliamo in Lezione6c.s. Questa routine e'
  361. quella DEFINITIVA, che potete usare quando volete scrivere qualcosa a video.
  362.  
  363. Perche' non disegnarsi il proprio font di caratteri? In Lezione6c2.s il FONT
  364. e' nel listato in dc.b come questo esempio:
  365.  
  366. ; "B"
  367.     dc.b    %01111110
  368.     dc.b    %01100011
  369.     dc.b    %01100011
  370.     dc.b    %01111110
  371.     dc.b    %01100011
  372.     dc.b    %01100011
  373.     dc.b    %01111110
  374.     dc.b    %00000000
  375.  
  376. I caratteri sono messi in memoria con dei dc.b % (binario). Potete cambiare
  377. ogni singolo carattere come volete. Se fate un vostro font, salvatelo su
  378. un disco formattato o sull'HARD DISK!
  379.  
  380.  
  381. Ora abbiamo l'occasione di provare una cosa che non abbiamo mai fatto prima:
  382. nello stesso schermo proviamo a far convivere una figura in LOWRES a 8 colori
  383. e un bitplane in HIRES. L'Amiga infatti puo' visualizzare contemporaneamente
  384. diverse risoluzioni video, (cosa che non mi risulta possa fare il PC MSDOS),
  385. basta mettere un WAIT nella copperlist e ridefinire sotto di esso il BPLCON0,
  386. proprio come se definissimo i colori per fare una sfumatura!
  387. Per esempio potremmo visualizzare dalla prima linea alla linea $50 una figura
  388. in HAM a 4096 colori in LOWRES, sotto di essa una in HIRES a 16 colori, sotto
  389. ancora una in LOWRES a 32 colori, e cosi' via. In alcuni giochi per esempio
  390. la schermata dove si muovono i personaggi e' in LOWRES, mentre il pannello
  391. con il punteggio e simili e' in HIRES (vedi AGONY).
  392. Visualizziamo subito la figura in LOWRES sopra una in HIRES in Lezione6d.s
  393.  
  394. Vediamo ora un "trucchetto" che ci permette di ottenere un effetto di "RILIEVO"
  395. alle parole che stampiamo: in Lezione6e.s attiviamo 2 bitplane anziche' 1 e
  396. sovrapponiamo il secondo al primo, ma il secondo spostato in basso di una
  397. linea. Cosa succede se mettiamo due immagini uguali trasparenti l'una
  398. sull'altra? L'immagine si sdoppia!!! E se scegliamo i colori giusti, facendo
  399. piu' chiaro lo sdoppiamento in "alto" e piu' scuro quello in "BASSO" cosa
  400. succede? Che abbiamo capito come funziona Lezione6e.s
  401.  
  402. A proposito di sovrapposizioni, perche' non attivare un bitplane "SOPRA" una
  403. figura per scriverci?? Vediamo in Lezione6f.s cosa succede.
  404.  
  405. In Lezione6g.s viene evidenziato l'effetto "TRASPARENZA" muovendo la scritta
  406. sopra la figura.
  407.  
  408. In Lezione6h.s, invece, troverete un modo per stampare testi a 3 colori,
  409. sovrapponendo due testi in due bitplanes.
  410.  
  411. In Lezione6i.s viene fatto lampeggiare uno dei 3 colori del testo, usando
  412. una TABELLA di valori predefiniti. Abbiamo gia' parlato di TABELLE nella
  413. LEZIONE1, ora vediamo in pratica il vantaggio che portano.
  414.  
  415. In Lezione6l.s viene usata una variazione della routine che legge da una TAB
  416. per var variare un colore; la variazione consiste nel fatto che anziche'
  417. leggere dall'inizio alla fine della tabella e ripartire da capo, rilegge la
  418. tabella all'indietro, cioe' dalla fine all'inizio.
  419.  
  420. Le tabelle possono essere utili o indispensabili per molti usi, ad esempio per
  421. simulare movimenti di rimbalzi o di oscillazioni. Vediamo in pratica la
  422. superiorita' dell'uso di una tabella rispetto a semplici ADD e SUB nel
  423. movimento di una figura in Lezione6m.s
  424.  
  425.  
  426. A proposito di movimento, per ora abbiamo visto lo scroll orizzontale tramite
  427. il BPLCON1 ($dff102) che permette uno scorrimento massimo di 16 pixel.
  428. Ma allora come si fa a scorrere lo schermo a destra e a sinistra quanto
  429. vogliamo?? La risposta e' abbastanza semplice: basta usare anche i puntatori
  430. ai bitplanes! Infatti, tramite i puntatori ai bitplanes abbiamo gia' visto
  431. che possiamo scorrere in alto e in basso, basta aggiungere o sottrarre la
  432. lunghezza di una linea (40 in lowres e 80 in HIRES). Ma possiamo scorrere
  433. anche in avanti e indietro, per la precisione a "scatti" di 8 pixel alla volta,
  434. basta sottrarre o aggiungere 1 al puntatore bitplane e abbiamo spostato a
  435. destra o a sinistra la figura di un byte, ossia 8 bit, ossia 8 pixel.
  436. Se possiamo scorrere di 8 pixel alla volta con i Bitplane Pointers e di 1 alla
  437. volta con il $dff102 (BPLCON1), bastera' scorrere 8 pixel uno alla volta col
  438. $dff102, appunto, poi "scattare" 8 pixel piu' avanti con un:
  439.  
  440.  subq.l #1,BITPLANEPOINTER
  441.  
  442. E azzerare contemporaneamente il BPLCON1 ($dff102), andando al nono pixel,
  443. dopodiche' scorrere di altri 8 pixel col $dff102 di un pixel alla volta,
  444. giungendo al pixel 9+8= 11, poi scattare in avanti di 8 pixel col Bitplane
  445. Pointer eccetera. Negli esempi pero', considerando che il $dff102 puo' scorrere
  446. fino ad un massimo di $FF, ossia da 0 a 15, e non solo da 0 a 7, ho adottato
  447. questa tecnica: per scorrere di 16 pixel alla volta basta aggiungere o
  448. sottrarre 2 ai puntatori bitplane (dato che con 1 spostavamo la PIC di 8 pixel)
  449. Dunque scorro un pixel alla volta col $dff102 usando la sua possibilita'
  450. massima, cioe' da $00 a $FF, totale 16 posizioni, dopodiche' "scatto" ai 16
  451. pixel seguenti con un ADDQ o SUBQ #2,BITPLANEPOINTERS.
  452. Ecco una routine che scorre verso destra un bitplane di un pixel alla volta per
  453. quanti pixel vogliamo: considerate che MIOBPCON1 e' il byte del $dff102
  454.  
  455.  
  456. Destra:
  457.     CMP.B    #$ff,MIOBPCON1    ; siamo arrivati al massimo scorrimento? (15)
  458.     BNE.s    CON1ADDA    ; se non ancora, scorri in avanti di 1
  459.                 ; con il BPLCON1
  460.  
  461. ;    Legge l'indirizzo del bitplane
  462.  
  463.     LEA    BPLPOINTERS,A1    ; Con queste 4 istruzioni preleviamo dalla
  464.     move.w    2(a1),d0    ; copperlist l'indirizzo dove sta puntando
  465.     swap    d0        ; attualmente il $dff0e0 e lo poiniamo in d0
  466.     move.w    6(a1),d0
  467.  
  468. ;    Scorre a destra di 16 pixel col puntatore bitplane
  469.  
  470.     subq.l    #2,d0        ; punta 16 bit piu' indietro ( la PIC scorre
  471.                 ; verso destra di 16 pixel)
  472.  
  473. ;    Fa ripartire da zero il BPLCON1
  474.  
  475.     clr.b    MIOBPCON1    ; azzera lo scroll hardware BPLCON1 ($dff102)
  476.                 ; infatti abbiamo "saltato" 16 pixel con il
  477.                 ; bitplane pointer, ora dobbiamo ricominciare
  478.                 ; da zero con il $dff102 per scattare a
  479.                 ; destra di un pixel alla volta.
  480.  
  481.     move.w    d0,6(a1)    ; copia la word BASSA dell'indirizzo del plane
  482.     swap    d0        ; scambia le 2 word
  483.     move.w    d0,2(a1)    ; copia la word ALTA dell'indirizzo del plane
  484.     rts            ; esci dalla routine
  485.  
  486. CON1ADDA:
  487.     add.b    #$11,MIOBPCON1    ; scorri a destra di 1 pixel la figura
  488.     rts            ; esci dalla routine
  489.  
  490.  
  491. La routine aumenta di uno il BPLCON1 ($dff102), facendolo passare per le 16
  492. posizioni possibili: 00,11,22,33,44,55,66,77,88,99,aa,bb,cc,dd,ee,ff dopodiche'
  493. salta al pixel ff+1 facendo 2 operazioni:
  494.  
  495. 1) Puntare 2 bytes (1 word, 16 bits) piu' indietro i puntatori bitplanes,
  496.    facendo scorrere a destra di 16 pixel la figura (dunque 1 pixel dopo la
  497.    posizione $FF, ossia 15 raggiunta il fotogramma precedente dal $dff102
  498.  
  499. 2) Azzerare il $dff102, dato che abbiamo "saltato" 16 pixel, altrimenti si
  500.    sommerebbero i 16 pixel aggiunti col Puntatore Bitplane e i 15 ($FF)
  501.    raggiunti col $dff102 (BPLCON1). Invece azzerando il BPLCON1 ripartiamo
  502.    da $00+16= sedicesimo pixel, dopodiche' andremo ai seguenti 15 con
  503.    il BPLCON1, lasciando inalterato il puntatore bitplane.
  504.  
  505. Se non fosse ancora chiaro, seguite questo schemino, tenendo presente che # e'
  506. la "figura" che spostiamo verso destra:
  507.  
  508.                 ; VAL. BPLCON1    - BYTE SOTTRATTI AI PUNT. PLANE
  509.  
  510. #                ;    $00    -    0    - tot. pixel:
  511.  #                ;    $11    -    0    -    1
  512.   #                ;    $22    -    0    -    2
  513.    #                ;    $33    -    0    -    3
  514.     #                ;    $44    -    0    -    4
  515.      #                ;    $55    -    0    -    5
  516.       #                ;    $66    -    0    -    6
  517.        #            ;    $77    -    0    -    7
  518.     #            ;    $88    -    0    -    8
  519.      #            ;    $99    -    0    -    9
  520.       #            ;    $aa    -    0    -    10
  521.        #            ;    $bb    -    0    -    11
  522.         #            ;    $cc    -    0    -    12
  523.          #            ;    $dd    -    0    -    13
  524.           #            ;    $ee    -    0    -    14
  525.            #        ;    $ff    -    0    -    15
  526.         #        ;    $00    -    2    -    16
  527.          #        ;    $11    -    2    -    17
  528.           #        ;    $22    -    2    -    18
  529.            #        ;    $33    -    2    -    19
  530.             #        ;    $44    -    2    -    20
  531.              #        ;    $55    -    2    -    21
  532.               #        ;    $66    -    2    -    22
  533.                #    ;    $77    -    2    -    23
  534.  
  535. eccetera....
  536.  
  537. Questo schema parla da solo: per esempio se vogliamo scorrere verso destra di
  538. 22 pixel un bitplane basta sottrarre 2 al bitplane pointer e mettere $66 al
  539. BPLCON1 ($dff102).
  540.  
  541. Per scorrere a sinistra dovremo invece aggiungere 2 ai puntatori bitplanes
  542. ogni 16 pixel e procedere al contrario con il $dff102: $ff,$ee,$dd.....
  543.  
  544. Vediamo in Lezione6n.s la routine in funzione.
  545. Noterete un'imprevisto: sul lato sinistro avviene un disturbo a scatti; questo
  546. non e' dovuto ad errori nella routine, ma ad una caratteristica dell'hardware
  547. di Amiga, per toglierlo basta un piccolo accorgimento gia' presente nelle
  548. modifiche consigliate del listato stesso.
  549.  
  550. Gia' che sappiamo scorrere quanto vogliamo anche in orizzontale, perche' non
  551. scorrere un bitplane piu' grande della finestra video?? Esattamente facciamo
  552. scorrere uno schermo largo 640 pixel in uno largo 320 spostandolo a destra e
  553. sinistra, tutto questo in Lezione6o.s
  554.  
  555. Abbiamo gia' visto per le tabelle l'utilizzo di una longword come puntatore
  556. ad un indirizzo:
  557.  
  558. PUNTATORE:
  559.     DC.L    TABELLA
  560.  
  561. Nella longword "PUNTATORE" viene assemblato l'indirizzo di tabella, per cui
  562. possiamo tenere "il conto" di dove siamo arrivati nella tabella aggiungendo
  563. o sottraendo la lunghezza di un elemento della tabella.
  564. Dobbiamo salvare l'indirizzo a cui siamo arrivati ogni volta perche' la
  565. routine viene eseguita ogni fotogramma e non continuamente, dunque possono
  566. essere eseguite anche altre routine prima che quella routine sia eseguita
  567. nuovamente. Quando questa routine viene rieseguita, deve continuare a prelevare
  568. valori dalla tabella da dove era rimasta la volta prima, e lo puo' fare
  569. leggendo l'indirizzo in PUNTATORE: con un semplice:
  570.  
  571.     MOVE.L    PUNTATORE(PC),d0    ; In d0 l'indirizzo dove siamo arrivati
  572.                     ; l'ultima volta.
  573.  
  574. Prima di uscire dalla routine bastera' salvare l'ultima posizione.
  575. Questo espediente puo' essere usato per molti scopi, per esempio per poter
  576. stampare un carattere solo ogni fotogramma, anziche' stampare tutto il testo
  577. e poi vederlo. Per fare cio' basta modificare la routine PRINT: e farsi due
  578. puntatori: uno che punti all'ultimo carattere stampato, ed uno che punti
  579. all'ultimo indirizzo nel bitplane dove abbiamo stampato l'ultimo carattere.
  580. In questo modo e' come se stampassimo un carattere, congelassimo la routine
  581. per tutto un fotogramma, la riattivassimo per stampare un carattere, poi la
  582. ricongelassimo eccetera. In realta' anziche' congelarla la eseguiamo per
  583. stampare un solo carattere, poi salviamo il punto dove siamo arrivati, usciamo
  584. dalla routine, aspettiamo che passi il fotogramma, rieseguiamo la routine
  585. ripartendo dal punto dov siamo arrivati, risalviamo tutto, usciamo eccetera.
  586. Il listato che mette in pratica questa possibilita' e' Lezione6p.s
  587.  
  588.  
  589. In un bitplane oltre che stampare testo possiamo anche creare disegni con
  590. routine apposite, come scacchiere, trame e tessiture. Basta porre ad 1 i bit
  591. giusti!!! In Lezione6q.s ci sono delle routine esempio.
  592.  
  593.  
  594. Siamo giunti alla fine della LEZIONE6, non ci resta che mettere insieme i
  595. listati e le "novita'" di questa lezione nel consueto listatone finale di
  596. esempio con musica: Lezione6r.s
  597.  
  598.  
  599. Ora passeremo allo studio degli sprite. Quello che dovete fare e' caricare
  600. la LEZIONE7.TXT, dopodiche' dovete cambiare il path per caricare gli incbin dei
  601. suoi listati, con "V DF0:SORGENTI3"
  602. I sorgenti, infatti, si trovano nella directory SORGENTI3 del disco 1.
  603.  
  604.